/**
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-12-08 15:07:43
 * Copyright (c) 2015- joysuch-版权所有
 */

package com.joysuch.wwyt.bp.service.impl;

import com.google.common.collect.Lists;
import com.joysuch.wwyt.bp.bean.contractor.BpContractorBean;
import com.joysuch.wwyt.bp.bean.contractor.BpContractorConstructionRecordBean;
import com.joysuch.wwyt.bp.entity.contractor.BpContractorConstructionRecord;
import com.joysuch.wwyt.bp.enums.DataStateTypes;
import com.joysuch.wwyt.bp.repository.BpContractorConstructionRecordManagementDao;
import com.joysuch.wwyt.bp.service.BpContractorConstructionRecordManagementService;
import com.joysuch.wwyt.bp.service.BpContractorService;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.util.Assert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Service
//@Transactional(rollbackFor = Exception.class)
@Slf4j
public class BpContractorConstructionRecordServiceImpl implements BpContractorConstructionRecordManagementService {

    @Autowired
    private BpContractorConstructionRecordManagementDao dao;
    @Autowired
    private BpContractorService contractorService;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;

    /**
     * 根据id查询
     * @param id
     * @return
     */
    @Override
    public ResultBean getById(Long id) {
        Assert.notNull(id, "id cannot be null");
        //查询施工管理表
        BpContractorConstructionRecord entity = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("此数据不存在"));
        BpContractorConstructionRecordBean bean = new BpContractorConstructionRecordBean();
        BeanUtils.copyProperties(entity, bean);
        //查询承包商信息
        if (entity != null && entity.getContractorId() != null){
            log.info("根据承包商id{}查询承包商信息",entity.getContractorId());
            ResultBean resultBean = contractorService.getById(entity.getContractorId());
            BpContractorBean contractorBean = (BpContractorBean) resultBean.getData();
            bean.setContractor(contractorBean);
            bean.setContractorName(contractorBean.getCompanyName());
        }
        return ResultBean.success(bean);
    }

    /**
     * 查询
     * @param page
     * @param contractorName
     * @return
     */
    @Override
//    @Transactional
    public Page<BpContractorConstructionRecordBean>  page(Pageable page, String contractorName) {
        page = PageDataUtils.addOrderByDesc(page, "id");
        Page<BpContractorConstructionRecord> list = null;
        // 根据姓名获取承包商id
        if (contractorName != null){
            List<Long> idsByName = contractorService.findIdsByName(contractorName);
            if (idsByName == null || idsByName.size() <= 0 ){
                List<BpContractorConstructionRecordBean> resultList = Lists.newArrayList();
                return new PageImpl<>(resultList, page, 0);
            }
            Specification<BpContractorConstructionRecord> specification = (Root<BpContractorConstructionRecord> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) -> {
                List<Predicate> predicates = new ArrayList<>();
                CriteriaBuilder.In<Object> planIdIn = cb.in(root.get("contractorId"));
                for (Long id : idsByName) {
                    planIdIn.value(id);
                }
                predicates.add(planIdIn);
                predicates.add(cb.equal(root.get("state"), DataStateTypes.EFFECTIVE.getState()));
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            };
            list = dao.findAll(specification, page);
        }else{
            list = dao.findAll(page);
        }
        List<BpContractorConstructionRecordBean> resultList = Lists.newArrayList();
        if (list != null && !list.isEmpty()) {
            for (BpContractorConstructionRecord entity : list) {
                BpContractorConstructionRecordBean bean = new BpContractorConstructionRecordBean();
                BeanUtils.copyProperties(entity, bean);
                log.info("根据承包商id{}查询承包商信息",entity.getContractorId());
                ResultBean resultBean = contractorService.getById(entity.getContractorId());
                BpContractorBean contractorBean = (BpContractorBean) resultBean.getData();
                bean.setContractor(contractorBean);
                bean.setContractorName(contractorBean.getCompanyName());
                resultList.add(bean);
            }
        }
        return new PageImpl<>(resultList, page, list == null ? 0 : list.getTotalElements());
    }

    /**
     * 新增字段后
     * @param bean
     * @return
     */
    @Override
//    @Transactional(rollbackFor = Exception.class)
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public ResultBean save(BpContractorConstructionRecordBean bean) {
        Long id = bean.getId();
        BpContractorConstructionRecord entity;
        if (id == null) {
            log.info("开始新增施工记录");
            entity = new BpContractorConstructionRecord();
            entity.setCode(bizCodeGeneratorFacade.chengbaoshangshigongguanli());
            entity.setState(DataStateTypes.EFFECTIVE.getState());
        } else {
            log.info("开始修改施工记录");
            entity = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("系统繁忙"));
            if (DataStateTypes.UN_EFFECTIVE.getState().equals(entity.getState())) {
                return ResultBean.fail(101, "此数据已作废");
            }
        }
        BeanUtils.copyProperties(bean, entity, "code", "state");
        dao.save(entity);
        return ResultBean.defaultSuccessResult();
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public ResultBean delete(Long id) {
        Assert.notNull(id, "id cannot be null");
        BpContractorConstructionRecord entity = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("此数据不存在"));
        dao.delete(entity);
        return ResultBean.defaultSuccessResult();
    }

    @Override
    public String getCode() {
        return bizCodeGeneratorFacade.chengbaoshangshigongguanli();
    }
}
